% \section{Implementation}
% \label{sec:implementation}
%
% There are two pieces to this package: a \LTX style file, and a
% Python module. They are mutually interdependent, so it makes sense to
% document them both here.
%
% \subsection{The style file}
% \label{sec:sty-file}
%
% \iffalse
% tell docstrip to put code into the .sty file
%<*latex>
% \fi
%
% All macros and counters intended for use internal to this package
% begin with ``|ST@|''.
%
% \subsubsection{Initialization}
%
% Let's begin by loading some packages. The key bits of |sageblock| and
% friends are stol---um, adapted from the |verbatim| package manual. So
% grab the |verbatim| package. We also need the |fancyvrb| package for
% the |sageexample| environment
%    \begin{macrocode}
\RequirePackage{verbatim}
\RequirePackage{fancyvrb}
%    \end{macrocode}
% and |listings| for the |sagecommandline| environment.
%    \begin{macrocode}
\RequirePackage{listings}
\RequirePackage{color}
\lstdefinelanguage{Sage}[]{Python}
  {morekeywords={False,sage,True},sensitive=true}
\lstdefinelanguage{SageOutput}[]{}
  {morekeywords={False,True},sensitive=true}
\lstdefinestyle{DefaultSageInputOutput}{
  nolol,
  identifierstyle=,
  name=sagecommandline,
  xleftmargin=5pt,
  numbersep=5pt,
  aboveskip=0pt,
  belowskip=0pt,
  breaklines=true,
  numberstyle=\footnotesize,
  numbers=right
}
\lstdefinestyle{DefaultSageInput}{
  language=Sage,
  style=DefaultSageInputOutput,
  basicstyle={\ttfamily\bfseries},
  commentstyle={\ttfamily\color{dgreencolor}},
  keywordstyle={\ttfamily\color{dbluecolor}\bfseries},
  stringstyle={\ttfamily\color{dgraycolor}\bfseries},
}
\lstdefinestyle{DefaultSageOutput}{
  language=SageOutput,
  style=DefaultSageInputOutput,
  basicstyle={\ttfamily},
  commentstyle={\ttfamily\color{dgreencolor}},
  keywordstyle={\ttfamily\color{dbluecolor}},
  stringstyle={\ttfamily\color{dgraycolor}},
}
\lstdefinestyle{SageInput}{
  style=DefaultSageInput,
}
\lstdefinestyle{SageOutput}{
  style=DefaultSageOutput,
}
\definecolor{dbluecolor}{rgb}{0.01,0.02,0.7}
\definecolor{dgreencolor}{rgb}{0.2,0.4,0.0}
\definecolor{dgraycolor}{rgb}{0.30,0.3,0.30}
%    \end{macrocode}
% Unsurprisingly, the |\sageplot| command works poorly without graphics
% support.
%    \begin{macrocode}
\RequirePackage{graphicx}
%    \end{macrocode}
% The |makecmds| package gives us a |\provideenvironment| which we need,
% and we use |ifpdf| and |ifthen| in |\sageplot| so we know what kind of
% files to look for.
%    \begin{macrocode}
\RequirePackage{makecmds}
\RequirePackage{ifpdf}
\RequirePackage{ifthen}
%    \end{macrocode}
%
% Next set up the counters, default indent, and flags.
%    \begin{macrocode}
\newcounter{ST@inline}
\newcounter{ST@plot}
\setcounter{ST@inline}{0}
\setcounter{ST@plot}{0}
\newlength{\sagetexindent}
\setlength{\sagetexindent}{5ex}
\newif\ifST@paused
\ST@pausedfalse
%    \end{macrocode}
% Set up the file stuff, which will get run at the beginning of the
% document, after we know what's happening with the |final| option.
% First, we open the |.sage| file:
%    \begin{macrocode}
\AtBeginDocument{\@ifundefined{ST@final}{%
\newwrite\ST@sf%
\immediate\openout\ST@sf=\jobname.sagetex.sage%
%    \end{macrocode}
% \begin{macro}{\ST@wsf}
%   We will write a lot of stuff to that file, so make a convenient
%   abbreviation, then use it to put the initial commands into the
%   |.sage| file. The hash mark below gets doubled when written to the
%   file, for some obscure reason related to parameter expansion. It's
%   valid Python, though, so I haven't bothered figuring out how to get
%   a single hash. We are assuming that the extension is |.tex|; see the
%   |initplot| documentation on page~\pageref{initplot} for discussion
%   of file extensions. The ``|(\jobname.sagetex.sage)|'' business is
%   there because the comment below will get pulled into the
%   autogenerated |.py| file (second order autogeneration!) and I'd like
%   to reduce possible confusion if someone is looking around in those
%   files. Finally, we check for version mismatch and bail if the .py
%   and .sty versions don't match and the user hasn't disabled checking.
%   Note that we use |^^J| and not |^^J%| when we need indented lines.
%   Also, |sagetex.py| now includes a |version| variable which
%   eliminates all the irritating string munging below, and later we can
%   remove this stuff and just use |sagetex.version|.
%   \changes{v2.2.4}{2010/02/15}{Add version mismatch checking.}
%    \begin{macrocode}
\newcommand{\ST@wsf}[1]{\immediate\write\ST@sf{#1}}%
\ST@wsf{%
# This file (\jobname.sagetex.sage) was *autogenerated* from \jobname.tex with
sagetex.sty version \ST@ver.^^J%
import sagetex^^J%
_st_ = sagetex.SageTeXProcessor('\jobname')^^J%
_do_ver_check_ = \ST@versioncheck^^J%
if _do_ver_check_ and sagetex.__version__.find('\ST@ver') == -1:^^J
  import sys^^J
  print '{0}.sage was generated with sagetex.sty version \ST@ver,'.format(
    sys.argv[0].split('.')[0])^^J
  print 'but is being processed by sagetex.py version {0}.'.format(
    ' '.join(sagetex.__version__.strip().strip('[').split()[0:2]))^^J
  print 'SageTeX version mismatch! Exiting.'^^J
  sys.exit(int(1))}}%
%    \end{macrocode}
% On the other hand, if the |ST@final| flag is set, don't bother with
% any of the file stuff, and make |\ST@wsf| a no-op.
%    \begin{macrocode}
{\newcommand{\ST@wsf}[1]{\relax}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ST@dodfsetup}
%   The |sageexample| environment writes stuff out to a different file
%   formatted so that one can run doctests on it. We define a macro that
%   only sets this up if necessary.
%    \begin{macrocode}
\newcommand{\ST@dodfsetup}{%
\@ifundefined{ST@diddfsetup}{%
\newwrite\ST@df%
\immediate\openout\ST@df=\jobname_doctest.sage%
\immediate\write\ST@df{r"""^^J%
This file was *autogenerated* from \jobname.tex with sagetex.sty^^J%
version \ST@ver. It contains the contents of all the^^J%
sageexample environments from \jobname.tex. You should be able to^^J%
doctest this file with "sage -t \jobname_doctest.sage".^^J%
^^J%
It is always safe to delete this file; it is not used in typesetting your^^J%
document.^^J}%
\AtEndDocument{\immediate\write\ST@df{"""}}%
\gdef\ST@diddfsetup{x}}%
{\relax}}
%    \end{macrocode}
% \changes{v2.2.5}{2010/03/25}{Write sageexample environment contents to
% a separate file, formatted for doctesting}
% \end{macro}
%
% \begin{macro}{\ST@wdf}
%   This is the compansion to |\ST@wsf|; it writes to the doctest file,
%   assuming that is has been set up. We ignore the |final| option here
%   since nothing in this file is relevant to typesetting the document.
%    \begin{macrocode}
\newcommand{\ST@wdf}[1]{\immediate\write\ST@df{#1}}
%    \end{macrocode}
% \end{macro}
%
% Now we declare our options, which mostly just set flags that we check
% at the beginning of the document, and when running the |.sage| file.
% \changes{v2.0}{2008/04/04}{Add \texttt{epstopdf} option}
% \changes{v2.0}{2008/12/16}{Add \texttt{final} option}
%
% The |final| option controls whether or not we write the |.sage| file;
% the |imagemagick| and |epstopdf| options both want to write something
% to that same file. So we put off all the actual file stuff until the
% beginning of the document---by that time, we'll have processed the
% |final| option (or not) and can check the |\ST@final| flag to see what
% to do. (We must do this because we can't specify code that runs if an
% option \emph{isn't} defined.)
%
% For |final|, we set a flag for other guys to check, and if there's no
% |.sout| file, we warn the user that something fishy is going on.
%    \begin{macrocode}
\DeclareOption{final}{%
  \newcommand{\ST@final}{x}%
  \IfFileExists{\jobname.sagetex.sout}{}{\AtEndDocument{\PackageWarningNoLine{sagetex}%
  {`final' option provided, but \jobname.sagetex.sout^^Jdoesn't exist! No Sage
    input will appear in your document. Remove the `final'^^Joption and
    rerun LaTeX on your document}}}}
%    \end{macrocode}
% For |imagemagick|, we set two flags: one for \LTX and one for Sage.
% It's important that we set |ST@useimagmagick| \emph{before} the
% beginning of the document, so that the graphics commands can check
% that. We do wait until the beginning of the document to do file
% writing stuff.
%    \begin{macrocode}
\DeclareOption{imagemagick}{%
  \newcommand{\ST@useimagemagick}{x}%
  \AtBeginDocument{%
  \@ifundefined{ST@final}{%
    \ST@wsf{_st_.useimagemagick = True}}{}}}
%    \end{macrocode}
% For |epstopdf|, we just set a flag for Sage.
%    \begin{macrocode}
\DeclareOption{epstopdf}{%
\AtBeginDocument{%
\@ifundefined{ST@final}{%
  \ST@wsf{_st_.useepstopdf = True}}{}}}
%    \end{macrocode}
% By default, we check to see if the .py and .sty file versions match.
% But we let the user disable this.
%    \begin{macrocode}
\newcommand{\ST@versioncheck}{True}
\DeclareOption{noversioncheck}{%
  \renewcommand{\ST@versioncheck}{False}}
\ProcessOptions\relax
%    \end{macrocode}
% The |\relax| is a little incantation suggested by the ``\LaTeXe{} for
% class and package writers'' manual, section 4.7.
%
% Pull in the |.sout| file if it exists, or do nothing if it doesn't. I
% suppose we could do this inside an |AtBeginDocument| but I don't see
% any particular reason to do that. It will work whenever we load it. If
% the |.sout| file isn't found, print the usual \TeX-style message. This
% allows programs
% (\href{http://www.phys.psu.edu/~collins/software/latexmk-jcc/}{\texttt{Latexmk}}, for example)
% that read the |.log| file or terminal output to detect
% the need for another typesetting run to do so. If the ``\texttt{No
%   file foo.sout}'' line doesn't work for some software package, please
% let me know and I can change it to use |PackageInfo| or whatever.
%    \begin{macrocode}
\InputIfFileExists{\jobname.sagetex.sout}{}
{\typeout{No file \jobname.sagetex.sout.}}
%    \end{macrocode}
% \changes{v2.1.1}{2009/05/14}{Add typeout if .sout file not found}
%
% The user might load the |hyperref| package after this one (indeed, the
% |hyperref| documentation insists that it be loaded last) or not at
% all---so when we hit the beginning of the document, provide a dummy
% |NoHyper| environment if one hasn't been defined by the |hyperref|
% package. We need this for the |\sage| macro below.
%    \begin{macrocode}
\AtBeginDocument{\provideenvironment{NoHyper}{}{}}
%    \end{macrocode}
%
% \subsubsection{The \texttt{\protect\bslash sage} and
% \texttt{\protect\bslash sagestr} macros}
% \label{sec:sagemacro}
%
% \begin{macro}{\ST@sage}
% \changes{v2.1.1}{2009/05/14}{Add ST@sage, sagestr, and refactor.}
% This macro combines |\ref|, |\label|, and Sage all at once. First, we
% use Sage to get a \LTX representation of whatever you give this
% function. The Sage script writes a |\newlabel| line into the |.sout|
% file, and we read the output using the |\ref| command. Usually, |\ref|
% pulls in a section or theorem number, but it will pull in arbitrary
% text just as well.
%
% The first thing it does it write its argument into the |.sage| file,
% along with a counter so we can produce a unique label. We wrap a
% try/except around the function call so that we can provide a more
% helpful error message in case something goes wrong. (In particular, we
% can tell the user which line of the |.tex| file contains the offending
% code.) Note the difference between |^^J| and |^^J%|: the newline
% immediately after the former puts a space into the output, and the
% percent sign in the latter supresses this.
%    \begin{macrocode}
\newcommand{\ST@sage}[1]{\ST@wsf{%
try:^^J
 _st_.inline(\theST@inline, #1)^^J%
except:^^J
 _st_.goboom(\the\inputlineno)}%
%    \end{macrocode}
% The |inline| function of the Python module is documented on page
% \pageref{inlinefn}. Back in \LTX-land: if paused, say so.
%    \begin{macrocode}
\ifST@paused
  \mbox{(Sage\TeX{} is paused)}%
%    \end{macrocode}
% Otherwise\ldots our use of |\newlabel| and |\ref| seems awfully clever
% until you load the |hyperref| package, which gleefully tries to
% hyperlink the hell out of everything. This is great until it hits one
% of our special |\newlabel|s and gets deeply confused. Fortunately the
% |hyperref| folks are willing to accomodate people like us, and give us
% a |NoHyper| environment.
%    \begin{macrocode}
\else
  \begin{NoHyper}\ref{@sageinline\theST@inline}\end{NoHyper}%
%    \end{macrocode}
% Now check if the label has already been defined. (The internal
% implementation of labels in \LTX involves defining a macro called
% ``|r@@labelname|''.) If it hasn't, we set a flag so that we can tell
% the user to run Sage on the |.sage| file at the end of the run.
%    \begin{macrocode}
  \@ifundefined{r@@sageinline\theST@inline}{\gdef\ST@rerun{x}}{}%
\fi
%    \end{macrocode}
% In any case, the last thing to do is step the counter.
%    \begin{macrocode}
\stepcounter{ST@inline}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\sage}
% This is the user-visible macro; it runs Sage's |latex()| on its
% argument.
%    \begin{macrocode}
\newcommand{\sage}[1]{\ST@sage{latex(#1)}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\sagestr}
% ilike above, but doesn't run latex
%    \begin{macrocode}
\newcommand{\sagestr}[1]{\ST@sage{#1}}
%    \end{macrocode}
%
% \end{macro}
%
% \begin{macro}{\percent}
% A macro that inserts a percent sign. This is more-or-less stolen from the
% \textsf{Docstrip} manual; there they change the catcode inside a group
% and use |gdef|, but here we try to be more \LaTeX y and use
% |\newcommand|.
%    \begin{macrocode}
\catcode`\%=12
\newcommand{\percent}{%}
\catcode`\%=14
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{The \texttt{\protect\bslash sageplot} macro and friends}
% \label{sec:sageplotmacro}
%
% Plotting is rather more complicated, and requires several helper
% macros that accompany |\sageplot|.
%
% \begin{macro}{\ST@plotdir}
% A little abbreviation for the plot directory. We don't use
% |\graphicspath| because it's
% \href{http://www.tex.ac.uk/cgi-bin/texfaq2html?label=graphicspath}{
% apparently slow}---also, since we know right where our plots are
% going, no need to have \LTX looking for them.
%    \begin{macrocode}
\newcommand{\ST@plotdir}{sage-plots-for-\jobname.tex}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ST@missingfilebox}
% The code that makes the ``file not found'' box. This shows up in a
% couple places below, so let's just define it once.
%    \begin{macrocode}
\newcommand{\ST@missingfilebox}{\framebox[2cm]{\rule[-1cm]{0cm}{2cm}\textbf{??}}}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\sageplot}
% \changes{v1.3}{2008/03/08}{Iron out warnings, cool \TikZ flowchart}
% This function is similar to |\sage|. The neat thing that we take
% advantage of is that commas aren't special for arguments to \LTX
% commands, so it's easy to capture a bunch of keyword arguments that
% get passed right into a Python function.
%
% This macro has two optional arguments, which can't be defined using
% \LTX's |\newcommand|; we use Scott Pakin's brilliant
% \href{http://tug.ctan.org/tex-archive/support/newcommand/}{|newcommand|}
% package to create this macro; the options I fed to his script were
% similar to this:
%\begin{center}
% |MACRO sageplot OPT[#1={width}] OPT[#2={notprovided}] #3|
%\end{center}
% Observe that we are using a Python script to write \LTX code which
% writes Python code which writes \LTX code. Crazy!
%
% Here's the wrapper command which does whatever magic we need to get
% two optional arguments.
%    \begin{macrocode}
\newcommand{\sageplot}[1][width=.75\textwidth]{%
  \@ifnextchar[{\ST@sageplot[#1]}{\ST@sageplot[#1][notprovided]}}
%    \end{macrocode}
% The first optional argument |#1| will get shoved right into the
% optional argument for |\includegraphics|, so the user has easy control
% over the \LTX aspects of the plotting. We define a default size of
% $3/4$ the textwidth, which seems reasonable. (Perhaps a future version
% of \ST will allow the user to specify in the package options a set of
% default options to be used throughout.) The second optional argument
% |#2| is the file format and allows us to tell what files to look for.
% It defaults to ``notprovided'', which tells the Python module to
% create EPS and PDF files. Everything in |#3| gets put into the Python
% function call, so the user can put in keyword arguments there which
% get interpreted correctly by Python.
%
% \begin{macro}{\ST@sageplot}
% \changes{v2.0}{2008/12/16}{Change to use only keyword arguments: see issue
% 2 on bitbucket tracker}
% Let's see the real code here. We write a couple lines to the |.sage|
% file, including a counter, input line number, and all of the mandatory
% argument; all this is wrapped in another try/except.
%    \begin{macrocode}
\def\ST@sageplot[#1][#2]#3{\ST@wsf{try:^^J
 _st_.plot(\theST@plot, format='#2', _p_=#3)^^Jexcept:^^J
 _st_.goboom(\the\inputlineno)}%
%    \end{macrocode}
% The Python |plot| function is documented on page~\pageref{plotfn}.
%
% Now we include the appropriate graphics file. Because the user might
% be producing DVI or PDF files, and have supplied a file format or not,
% and so on, the logic we follow is a bit complicated.
% \autoref{f:sageplottree} shows what we do; for completeness---and
% because I think drawing trees with \TikZ is really cool---we show what
% |\ST@inclgrfx| does in \autoref{f:stig}. This entire complicated
% business is intended to avoid doing an |\includegraphics| command on a
% file that doesn't exist, and to issue warnings appropriate to the
% situation.
%
% \begin{figure}
%   \centering
%   \begin{tikzpicture}
%     \tikzstyle{level 1}=[sibling distance=6cm]
%     \tikzstyle{level 2}=[sibling distance=3cm]
%     \node [box] {DVI or PDF?}
%       child {node [box] {Format provided?}
%         child {node [box] {STig EPS}
%           edge from parent node[left] {no}}
%         child {node [box] {IM option set?}
%           child {node [box, text width=3cm] {Warn that DVI + PNG = bad}
%             edge from parent node[left] {no}}
%           child {node [box] {STig EPS}
%             edge from parent node[right] {yes}}
%           edge from parent node[right] {yes}}
%         edge from parent node[left] {DVI}}
%       child {node [box] {Format provided?}
%         child {node [box] {STig PDF}
%           edge from parent node[left] {no}}
%         child {node [box] {STig \texttt{\#2}}
%           edge from parent node[right] {yes}}
%         edge from parent node[right] {PDF}};
%   \end{tikzpicture}
%   \caption{The logic tree that \texttt{\bslash sageplot} uses to
%   decide whether to run \texttt{\bslash includegraphics} or to yell at
%   the user. ``Format'' is the \texttt{\#2} argument to \texttt{\bslash
%   sageplot}, ``STig ext''
%   means a call to \texttt{\bslash ST@inclgrfx} with ``ext'' as the
%   second argument, and ``IM'' is Imagemagick.}
%   \label{f:sageplottree}
% \end{figure}
%
% If we are creating a PDF, we check to see if the user asked for a
% different format, and use that if necessary:
%    \begin{macrocode}
\ifpdf
  \ifthenelse{\equal{#2}{notprovided}}%
    {\ST@inclgrfx{#1}{pdf}}%
    {\ST@inclgrfx{#1}{#2}}%
%    \end{macrocode}
% Otherwise, we are creating a DVI file, which only supports EPS. If the
% user provided a format anyway, don't include the file (since it won't
% work) and warn the user about this. (Unless the file doesn't exist, in
% which case we do the same thing that |\ST@inclgrfx| does.)
%    \begin{macrocode}
\else
  \ifthenelse{\equal{#2}{notprovided}}%
    {\ST@inclgrfx{#1}{eps}}%
%    \end{macrocode}
% If a format is provided, we check to see if we're using the
% imagemagick option. If not, we're going to issue some sort of warning,
% depending on whether the file exists yet or not.
%    \begin{macrocode}
    {\@ifundefined{ST@useimagemagick}%
      {\IfFileExists{\ST@plotdir/plot-\theST@plot.#2}%
        {\ST@missingfilebox%
         \PackageWarning{sagetex}{Graphics file
         \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space
         cannot be used with DVI output. Use pdflatex or create an EPS
         file. Plot command is}}%
        {\ST@missingfilebox%
         \PackageWarning{sagetex}{Graphics file
         \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space
         does not exist. Plot command is}%
         \gdef\ST@rerun{x}}}%
%    \end{macrocode}
% Otherwise, we are using Imagemagick, so try to include an EPS file
% anyway.
%    \begin{macrocode}
    {\ST@inclgrfx{#1}{eps}}}%
\fi
%    \end{macrocode}
% Step the counter and we're done with the usual work.
%    \begin{macrocode}
\stepcounter{ST@plot}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\ST@inclgrfx}
% This command includes the requested graphics file (|#2| is the
% extension) with the requested options (|#1|) if the file exists. Note
% that it just needs to know the extension, since we use a counter for
% the filename. If we are paused, it just puts in a little box saying
% so.
%    \begin{macrocode}
\newcommand{\ST@inclgrfx}[2]{\ifST@paused
  \fbox{\rule[-1cm]{0cm}{2cm}Sage\TeX{} is paused; no graphic}
\else
  \IfFileExists{\ST@plotdir/plot-\theST@plot.#2}%
    {\includegraphics[#1]{\ST@plotdir/plot-\theST@plot.#2}}%
%    \end{macrocode}
% If the file doesn't exist, we try one more thing before giving up: the
% Python module will automatically fall back to saving as a PNG file if
% saving as an EPS or PDF file fails. So if making a PDF, we look for a
% PNG file.
%
% If the file isn't there, we insert a little box to indicate it wasn't
% found, issue a warning that we didn't find a graphics file, then set a
% flag that, at the end of the run, tells the user to run Sage again.
%    \begin{macrocode}
    {\IfFileExists{\ST@plotdir/plot-\theST@plot.png}%
       {\ifpdf
           \ST@inclgrfx{#1}{png}
         \else
           \PackageWarning{sagetex}{Graphics file
           \ST@plotdir/plot-\theST@plot.png on page \thepage\space not
            supported; try using pdflatex. Plot command is}%
        \fi}%
       {\ST@missingfilebox%
       \PackageWarning{sagetex}{Graphics file
       \ST@plotdir/plot-\theST@plot.#2\space on page \thepage\space does not
       exist. Plot command is}%
       \gdef\ST@rerun{x}}}
\fi}
%    \end{macrocode}
% \autoref{f:stig} makes this a bit clearer.
% \begin{figure}
%   \centering
%   \begin{tikzpicture}
%     \tikzstyle{level 1}=[sibling distance=4cm]
%     \node [box] {Paused?}
%       child {node [box] {Insert ``we're paused'' box}
%         edge from parent node[left] {yes}}
%       child {node [box] {Does EXT file exist?}
%         child {node [box] {Does a PNG file exist?}
%           child {node [box] {Making a PDF?}
%             child {node [box] {\texttt{includegraphics} PNG}
%               edge from parent node[left] {yes}}
%             child {node [box, text width=2cm] {Warning: DVI, latex incompatible}
%               edge from parent node[left] {no}}
%             edge from parent node[left] {yes}}
%           child {node [box, text width = 2.125cm] {Warn user to rerun Sage}
%             edge from parent node[left] {no}}
%           edge from parent node[left] {no}}
%         child {node [box] {Use \texttt{includegraphics}}
%           edge from parent node[right] {yes}}
%         edge from parent node[right] {no}};
%   \end{tikzpicture}
%   \caption{The logic used by the \texttt{\bslash ST@inclgrfx}
%   command.}
%   \label{f:stig}
% \end{figure}
% \end{macro}
%
% \subsubsection{Verbatim-like environments}
% \label{sec:verbatim-envs}
%
% \begin{macro}{\ST@beginsfbl}
% This is ``begin |.sage| file block'', an internal-use abbreviation
% that sets things up when we start writing a chunk of Sage code to
% the |.sage| file. It begins with some \TeX{} magic that fixes
% spacing, then puts the start of a try/except block in the |.sage|
% file---this not only allows the user to indent code without
% Sage/Python complaining about indentation, but lets us tell the user
% where things went wrong. The |blockbegin| and |blockend| functions
% are documented on page~\pageref{blocksbeginend}. The last bit is some
% magic from the |verbatim| package manual that makes \LTX respect
% line breaks.
%    \begin{macrocode}
\newcommand{\ST@beginsfbl}{%
  \@bsphack\ST@wsf{%
_st_.blockbegin()^^Jtry:}%
  \let\do\@makeother\dospecials\catcode`\^^M\active}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ST@endsfbl}
% The companion to |\ST@beginsfbl|.
%    \begin{macrocode}
\newcommand{\ST@endsfbl}{%
\ST@wsf{except:^^J
 _st_.goboom(\the\inputlineno)^^J_st_.blockend()}}
%    \end{macrocode}
% \end{macro}
%
% Now let's define the ``verbatim-like'' environments. There are four
% possibilities, corresponding to the two independent choices of
% typesetting the code or not, and writing to the |.sage| file or not.
%
% \begin{environment}{sageblock}
% This environment does both: it typesets your code and puts it into the
% |.sage| file for execution by Sage.
%    \begin{macrocode}
\newenvironment{sageblock}{\ST@beginsfbl%
%    \end{macrocode}
% The space between |\ST@wsf{| and |\the| is crucial! It, along with the
% ``|try:|'', is what allows the user to indent code if they like. This
% line sends stuff to the |.sage| file.
%    \begin{macrocode}
\def\verbatim@processline{\ST@wsf{ \the\verbatim@line}%
%    \end{macrocode}
% Next, we typeset your code and start the verbatim environment.
%    \begin{macrocode}
\hspace{\sagetexindent}\the\verbatim@line\par}%
\verbatim}%
%    \end{macrocode}
% At the end of the environment, we put a chunk into the |.sage| file
% and stop the verbatim environment.
%    \begin{macrocode}
{\ST@endsfbl\endverbatim}
%    \end{macrocode}
% \end{environment}
%
% \begin{environment}{sagesilent}
% This is from the |verbatim| package manual. It's just like the above,
% except we don't typeset anything.
%    \begin{macrocode}
\newenvironment{sagesilent}{\ST@beginsfbl%
\def\verbatim@processline{\ST@wsf{ \the\verbatim@line}}%
\verbatim@start}%
{\ST@endsfbl\@esphack}
%    \end{macrocode}
% \end{environment}
%
% \begin{environment}{sageverbatim}
% The opposite of |sagesilent|. This is exactly the same as the verbatim
% environment, except that we include some indentation to be consistent
% with other typeset Sage code.
%    \begin{macrocode}
\newenvironment{sageverbatim}{%
\def\verbatim@processline{\hspace{\sagetexindent}\the\verbatim@line\par}%
\verbatim}%
{\endverbatim}
%    \end{macrocode}
% \end{environment}
%
% Logically, we now need an environment which neither typesets
% \emph{nor} writes code to the |.sage| file. The verbatim package's
% |comment| environment does that.\\
%
% \begin{environment}{sageexample}
%   Finally, we have an environment which is mostly-but-not-entirely
%   verbatim; this is the example environment, which takes input like
%   Sage doctests, and prints out the commands verbatim but nicely
%   typesets the output of those commands. This and the corresponding
%   Python function are due to Nicolas M. Thi\'ery.
%    \begin{macrocode}
\newcommand{\sageexampleincludetextoutput}{False}
\newenvironment{sageexample}{%
   \ST@wsf{%
try:^^J
 _st_.doctest(\theST@inline, r"""}%
   \ST@dodfsetup%
   \ST@wdf{Sage example, line \the\inputlineno::^^J}%
   \begingroup%
   \@bsphack%
   \let\do\@makeother\dospecials%
   \catcode`\^^M\active%
   \def\verbatim@processline{%
     \ST@wsf{\the\verbatim@line}%
     \ST@wdf{\the\verbatim@line}%
   }%
   \verbatim@start%
}
{
  \@esphack%
  \endgroup%
  \ST@wsf{%
    """, globals(), locals(), \sageexampleincludetextoutput)^^Jexcept:^^J
    _st_.goboom(\the\inputlineno)}%
  \ifST@paused%
    \mbox{(Sage\TeX{} is paused)}%
  \else%
    \begin{NoHyper}\ref{@sageinline\theST@inline}\end{NoHyper}%
    \@ifundefined{r@@sageinline\theST@inline}{\gdef\ST@rerun{x}}{}%
  \fi%
  \ST@wdf{}%
  \stepcounter{ST@inline}}
%    \end{macrocode}
% \changes{v2.2.4}{2010/03/14}{Add first support for
%   \texttt{sageexample} environment}
% \end{environment}
%
%
% \begin{environment}{sagecommandline}
% This environment is similar to the |sageexample| environment, but
% typesets the sage output as text with python syntax highlighting.
%    \begin{macrocode}
\newcommand{\sagecommandlinetextoutput}{True}
\newlength{\sagecommandlineskip}
\setlength{\sagecommandlineskip}{8pt}
\newenvironment{sagecommandline}{%
   \ST@wsf{%
try:^^J
 _st_.commandline(\theST@inline, r"""}%
   \ST@dodfsetup%
   \ST@wdf{Sage commandline, line \the\inputlineno::^^J}%
   \begingroup%
   \@bsphack%
   \let\do\@makeother\dospecials%
   \catcode`\^^M\active%
   \def\verbatim@processline{%
     \ST@wsf{\the\verbatim@line}%
     \ST@wdf{\the\verbatim@line}%
   }%
   \verbatim@start%
}
{
  \@esphack%
  \endgroup%
  \ST@wsf{%
    """, globals(), locals(), \sagecommandlinetextoutput)^^Jexcept:^^J
    _st_.goboom(\the\inputlineno)}%
  \ifST@paused%
    \mbox{(Sage\TeX{} is paused)}%
  \else%
    \begin{NoHyper}\ref{@sageinline\theST@inline}\end{NoHyper}%
    \@ifundefined{r@@sageinline\theST@inline}{\gdef\ST@rerun{x}}{}%
  \fi%
  \ST@wdf{}%
  \stepcounter{ST@inline}}
%    \end{macrocode}
% \end{environment}
%
% \subsubsection{Pausing \ST}
% \label{sec:pausing-sagetex}
%
% How can one have Sage to stop processing \ST output for a little
% while, and then start again? At first I thought I would need some sort
% of ``goto'' statement in Python, but later realized that there's a
% dead simple solution: write triple quotes to the |.sage| file to
% comment out the code. Okay, so this isn't \emph{really} commenting out
% the code; PEP 8 says block comments should use ``|#|'' and Sage will
% read in the ``commented-out'' code as a string literal. For the
% purposes of \ST, I think this is a good decision, though, since (1)
% the pausing mechanism is orthogonal to everything else, which makes it
% easier to not screw up other code, and (2) it will always work.
%
% This illustrates what I really like about \ST: it mixes \LTX and
% Sage/Python, and often what is difficult or impossible in one system
% is trivial in the other.
%
% \begin{macro}{sagetexpause}
% This macro pauses \ST by effectively commenting out code in the
% |.sage| file. When running the corresponding |.sage| file, Sage will
% skip over any commands issued while \ST is paused.
%    \begin{macrocode}
\newcommand{\sagetexpause}{\ifST@paused\relax\else
\ST@wsf{print 'SageTeX paused on \jobname.tex line \the\inputlineno'^^J"""}
\ST@pausedtrue
\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{sagetexunpause}
% This is the obvious companion to |\sagetexpause|.
%    \begin{macrocode}
\newcommand{\sagetexunpause}{\ifST@paused
\ST@wsf{"""^^Jprint 'SageTeX unpaused on \jobname.tex line \the\inputlineno'}
\ST@pausedfalse
\fi}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{End-of-document cleanup}
% \label{sec:end-of-doc-cleanup}
%
% We tell the Sage script to write some information to the |.sout| file,
% then check to see if |ST@rerun| ever got defined. If not, all the
% inline formulas and plots worked, so do nothing. We check to see if
% we're paused first, so that we can finish the triple-quoted string in
% the |.sage| file.
%    \begin{macrocode}
\AtEndDocument{\ifST@paused
\ST@wsf{"""^^Jprint 'SageTeX unpaused at end of \jobname.tex'}
\fi
\ST@wsf{_st_.endofdoc()}%
\@ifundefined{ST@rerun}{}%
%    \end{macrocode}
% Otherwise, we issue a warning to tell the user to run Sage on the
% |.sage| file. Part of the reason we do this is that, by using |\ref|
% to pull in the inlines, \LTX will complain about undefined references
% if you haven't run the Sage script---and for many \LTX users, myself
% included, the warning ``there were undefined references'' is a signal
% to run \LTX again. But to fix these particular undefined references,
% you need to run \emph{Sage}. We also suppress file-not-found errors
% for graphics files, and need to tell the user what to do about that.
%
% At any rate, we tell the user to run Sage if it's necessary.
%    \begin{macrocode}
{\typeout{*********************************************************************}
\PackageWarningNoLine{sagetex}{there were undefined Sage formulas and/or
plots.^^JRun Sage on \jobname.sagetex.sage, and then run LaTeX on \jobname.tex
again}}
\typeout{*********************************************************************}}
%    \end{macrocode}
%
%
% \subsection{The Python module}
% \label{sec:py-file}
%
% \iffalse
% Hey, docstrip! Stop putting code into the .sty file, and start
% putting it into the .py file.
%</latex>
%<*python>
% Thanks.
% \fi
%
% The style file writes things to the |.sage| file and reads them from
% the |.sout| file. The Python module provides functions that help
% produce the |.sout| file from the |.sage| file.
%
% \paragraph{A note on Python and \textsf{Docstrip}} There is one tiny
% potential source of confusion when documenting Python code with
% \textsf{Docstrip}: the percent sign. If you have a long line of Python
% code which includes a percent sign for string formatting and you break
% the line with a backslash and begin the next line with a percent sign,
% that line \emph{will not} be written to the output file. This is only
% a problem if you \emph{begin} the line with a (single) percent sign;
% there are no troubles otherwise.\\
%
% On to the code: the |sagetex.py| file is intended to be used as a
% module and doesn't do anything useful when called directly, so if
% someone does that, warn them. We do this right away so that we print
% this and exit before trying to import any Sage modules; that way, this
% error message gets printed whether you run the script with Sage or
% with Python. Since \ST is now distributed with Sage and |sagetex.py|
% now lives almost exclusively deep within the Sage ecosystem, this
% check is not so necessary and will be removed sometime soon.
%    \begin{macrocode}
import sys
if __name__ == "__main__":
  print("""This file is part of the SageTeX package.
It is not meant to be called directly.

This file will be automatically used by Sage scripts generated from a
LaTeX document using the SageTeX package.""")
  sys.exit()
%    \end{macrocode}
% Munge the version string (which we get from
% \texttt{sagetexpackage.dtx}) to extract what we want, then import what
% we need:
%    \begin{macrocode}
version = ' '.join(__version__.strip('[').split()[0:2])
from sage.misc.latex import latex
from sage.misc.preparser import preparse
import os
import os.path
import hashlib
import traceback
import subprocess
import shutil
%    \end{macrocode}
% We define a class so that it's a bit easier to carry around internal
% state. We used to just have some global variables and a bunch of
% functions, but this seems a bit nicer and easier.
%    \begin{macrocode}
class SageTeXProcessor():
  def __init__(self, jobname):
    self.progress('Processing Sage code for {0}.tex...'.format(jobname))
    self.didinitplot = False
    self.useimagemagick = False
    self.useepstopdf = False
    self.plotdir = 'sage-plots-for-' + jobname + '.tex'
    self.filename = jobname
    self.name = os.path.splitext(jobname)[0]
    autogenstr = """% This file was *autogenerated* from {0}.sagetex.sage with
 % sagetex.py version {1}\n""".format(self.name, version)
%    \end{macrocode}
% Don't remove the space before the percent sign above!
%
% Open a |.sout.tmp| file and write all our output to that. Then, when
% we're done, we move that to |.sout|. The ``autogenerated'' line is
% basically the same as the lines that get put at the top of preparsed
% Sage files; we are automatically generating a file with Sage, so it
% seems reasonable to add it. Add in the version to help debugging
% version mismatch problems.
%    \begin{macrocode}
    self.souttmp = open(self.filename + '.sagetex.sout.tmp', 'w')
    self.souttmp.write(autogenstr)
%    \end{macrocode}
% In addition to the |.sout| file, the |sagecommandline| also needs a
% |.scmd| file. As before, we use a |.scmd.tmp| file and rename it
% later on. We store the file and position in the data members
%    \begin{macrocode}
    self.scmdtmp = open(self.filename + '.sagetex.scmd.tmp', 'w')
    self.scmdtmp.write(autogenstr)
    self.scmdpos = 3
%    \end{macrocode}
%
% \begin{macro}{progress}
% This function just prints stuff. It allows us to not print a
% linebreak, so you can get ``|start...|'' (little time spent
% processing) ``|end|'' on one line.
%    \begin{macrocode}
  def progress(self, t,linebreak=True):
    if linebreak:
      print(t)
    else:
      sys.stdout.write(t)
      sys.stdout.flush()
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{initplot}
% \phantomsection\label{initplot}
% We only want to create the plots directory if the user actually plots
% something. This function creates the directory and sets the
% |didinitplot| flag after doing so. We make a directory based on the
% \LTX file being processed so that if there are multiple |.tex| files
% in a directory, we don't overwrite plots from another file.
%    \begin{macrocode}
  def initplot(self):
    self.progress('Initializing plots directory')
%    \end{macrocode}
% We hard-code the |.tex| extension, which is fine in the overwhelming
% majority of cases, although it does cause minor confusion when
% building the documentation. If it turns out lots of people use, say, a
% |ltx| extension or whatever, We could find out the correct extension,
% but it would involve a lot of irritating mucking around---on
% |comp.text.tex|, the best solution I found for finding the file
% extension is to look through the |.log| file.
%    \begin{macrocode}
    if os.path.isdir(self.plotdir):
      shutil.rmtree(self.plotdir)
    os.mkdir(self.plotdir)
    self.didinitplot = True
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{inline}
% \phantomsection\label{inlinefn}
% This function works with |\sage| from the style file (see
% \autoref{sec:sagemacro}) to put Sage output into your \LTX file.
% Usually, when you use |\label|, it writes a line such as
% \begin{center}
%   |\newlabel{labelname}{{section number}{page number}}|
% \end{center}
% to the |.aux| file. When you use the |hyperref| package, there are
% more fields in the second argument, but the first two are the same.
% The |\ref| command just pulls in what's in the first field of the
% second argument, so we can hijack this mechanism for our own nefarious
% purposes. The function writes a |\newlabel| line with a label made
% from a counter and the text from running Sage on |s|.
%
% We print out the line number so if something goes wrong, the user can
% more easily track down the offending |\sage| command in the source
% file.
%
% That's a lot of explanation for a very short function:
%    \begin{macrocode}
  def inline(self, counter, s):
    self.progress('Inline formula {0}'.format(counter))
    self.souttmp.write('\\newlabel{@sageinline' + str(counter) + '}{{%\n' +
                 s.rstrip() + '}{}{}{}{}}\n')
%    \end{macrocode}
% We are using five fields, just like |hyperref| does, because that
% works whether or not |hyperref| is loaded. Using two fields, as in
% plain \LTX, doesn't work if |hyperref| is loaded.
% \end{macro}

% \begin{macro}{savecmd}
%   Analogous to |inline|, this method saves the input string |s| to
%   the temporary |.scmd| file. As an added bonus, it returns a pair
%   of line numbers in the |.scmd| file, the first and last line of
%   the newly-added output.
%    \begin{macrocode}
  def savecmd(self, counter, s):
    self.progress('Sage commandline {0}'.format(counter))
    self.scmdtmp.write(s.rstrip() + "\n")
    begin = self.scmdpos
    end = begin + len(s.splitlines()) - 1
    self.scmdpos = end+1
    return begin, end
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{blockbegin}
% \begin{macro}{blockend}
% \phantomsection\label{blocksbeginend}
% This function and its companion used to write stuff to the |.sout|
% file, but now they just update the user on our progress evaluating a
% code block. The verbatim-like environments of
% \autoref{sec:verbatim-envs} use these functions.
%    \begin{macrocode}
  def blockbegin(self):
    self.progress('Code block begin...', False)
  def blockend(self):
    self.progress('end')
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{doctest}
% This function handles the |sageexample| environment, which typesets
% Sage code and its output. We call it doctest because the format is
% just like that for doctests in the Sage library.
%    \begin{macrocode}
  def doctest(self, counter, str, globals, locals, include_text_output):
      print 'in doctest'
      current_statement = None
      current_lines = None
      latex_string = ""
      line_iterator = (line.lstrip() for line in str.splitlines())

      # Gobbles everything until the first "sage: ..." block
      for line in line_iterator:
          if line.startswith("sage: "):
              break
      else:
          return
      sage_block = 0
      while True:
          # At each
          assert line.startswith("sage: ")
          current_statement  = line[6:]
          current_lines = "  "+line
          for line in line_iterator:
              if line.startswith("sage: "):
                  break
              elif line.startswith("..."):
                  current_statement +="\n"+line[6:]
                  current_lines +="\n  "+line
              elif include_text_output:
                  current_lines +="\n  "+line
          else:
              line = None # we reached the last line
          # Now we have digested everything from the current sage: ... to the next one or to the last line
          # Let us handle it
          verbatimboxname = "@sageinline%s-code%s"%(counter,sage_block)
          self.souttmp.write("\\begin{SaveVerbatim}{%s}\n"%verbatimboxname)
          self.souttmp.write(current_lines)
          self.souttmp.write("\n\\end{SaveVerbatim}\n")
          latex_string += "\UseVerbatim{%s}\n"%verbatimboxname
          current_statement = preparse(current_statement)
          try: # How to test whether the code is an Python expression or a statement?
              # In the first case, we compute the result and include it in the latex
              result = eval(current_statement, globals, locals)
%    \end{macrocode}
% The verbatim stuff seems to end with a bit of vertical space, so don't
% start the displaymath environment with unnecessary vertical
% space---the displayskip stuff is from \S 11.5 of Herbert Vo\ss's
% ``\href{http://www.ctan.org/tex-archive/info/math/voss/mathmode/}{Math
%   Mode}''. Be careful when using \TeX{} commands and Python 3 (or
% 2.6+) curly brace string formatting; either double braces or separate
% strings, as below.
%    \begin{macrocode}
              latex_string += r"""\abovedisplayskip=0pt plus 3pt
\abovedisplayshortskip=0pt plus 3pt
\begin{displaymath}""" + "\n {0}\n".format(latex(result)) + r"\end{displaymath}" + "\n"
          except SyntaxError:
              # If this fails, we assume that the code was a statement, and just execute it
              exec current_statement in globals, locals
          current_lines = current_statement = None
          if line is None: break
          sage_block += 1
      self.inline(counter, latex_string)
%    \end{macrocode}
% \changes{v2.2.5}{2010/03/25}{Fix up spacing in sageexample displaymath envs}
% \end{macro}
%
% \begin{macro}{commandline}
%   This function handles the |commandline| environment, which
%   typesets Sage code and its output.
%    \begin{macrocode}
  def commandline(self, counter, str, globals, locals, text_output):
      current_statement = None
      current_lines = None
      line_iterator = (line.lstrip() for line in str.splitlines())
      latex_string = r"\vspace{\sagecommandlineskip}" + "\n"
      bottom_skip = ''

      # Gobbles everything until the first "sage: ..." block
      for line in line_iterator:
          if line.startswith("sage: "):
              break
      else:
          return
      sage_block = 0
      while True:
          # At each
          assert line.startswith("sage: ")
          current_statement  = line[6:]
          current_lines = line
          for line in line_iterator:
              if line.startswith("sage: "):
                  break
              elif line.startswith("...   "):
                  current_statement += "\n"+line[6:]
                  current_lines += "\n"+line
          else:
              line = None # we reached the last line
          # Now have everything from "sage:" to the next "sage:"

          if current_lines.find('#@')>=0:
              escapeoption = ',escapeinside={\\#@}{\\^^M}'
          else:
              escapeoption = ''

          begin, end = self.savecmd(counter,current_lines)
          latex_string += r"\lstinputlisting[firstline={0},lastline={1},firstnumber={2},style=SageInput{3}]{{{4}.sagetex.scmd}}".format(begin, end, begin-2, escapeoption, self.name)+"\n"

          current_statement = preparse(current_statement)
          try:  # is it an expression?
              result = eval(current_statement, globals, locals)
              resultstr = "{0}".format(result)
              begin, end = self.savecmd(counter,resultstr)
              if text_output:
                latex_string += r"\lstinputlisting[firstline={0},lastline={1},firstnumber={2},style=SageOutput]{{{3}.sagetex.scmd}}".format(begin, end, begin-2, self.name)+"\n"
                bottom_skip = r"\vspace{\sagecommandlineskip}" + "\n"
              else:
                latex_string += (
                  r"\begin{displaymath}" + "\n" +
                  latex(result)          + "\n" +
                  r"\end{displaymath}"   + "\n" )
                bottom_skip = ''
          except SyntaxError:  # must be a statement!
              exec current_statement in globals, locals
          current_lines = current_statement = None
          if line is None: break
          sage_block += 1
      latex_string += bottom_skip + r"\noindent" + "\n"
      self.inline(counter, latex_string)
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{plot}
% \phantomsection\label{plotfn}
% I hope it's obvious that this function does plotting. It's the Python
% counterpart of |\ST@sageplot| described in \autoref{sec:sageplotmacro}. As
% mentioned in the |\sageplot| code, we're taking advantage of two
% things: first, that \LTX doesn't treat commas and spaces in macro
% arguments specially, and second, that Python (and Sage plotting
% functions) has nice support for keyword arguments. The |#3| argument
% to |\sageplot| becomes |_p_| and |**kwargs| below.
%    \begin{macrocode}
  def plot(self, counter, _p_, format='notprovided', **kwargs):
      if not self.didinitplot:
          self.initplot()
      self.progress('Plot {0}'.format(counter))
%    \end{macrocode}
% If the user says nothing about file formats, we default to producing
% PDF and EPS. This allows the user to transparently switch between
% using a DVI previewer (which usually automatically updates when the
% DVI changes, and has support for source specials, which makes the
% writing process easier) and making PDFs.\footnote{Yes, there's
% \texttt{pdfsync}, but full support for that is still rare in Linux, so
% producing EPS and PDF is the best solution for now.}
%    \begin{macrocode}
      if format == 'notprovided':
          formats = ['eps', 'pdf']
      else:
          formats = [format]
      for fmt in formats:
%    \end{macrocode}
% If we're making a PDF and have been told to use |epstopdf|, do so,
% then skip the rest of the loop.
%    \begin{macrocode}
          if fmt == 'pdf' and self.useepstopdf:
              epsfile = os.path.join(self.plotdir, 'plot-{0}.eps'.format(counter))
              self.progress('Calling epstopdf to convert plot-{0}.eps to PDF'.format(
                            counter))
              subprocess.check_call(['epstopdf', epsfile])
              continue
%    \end{macrocode}
% Some plot objects (mostly 3-D plots) do not support saving to EPS or
% PDF files (yet), but everything can be saved to a PNG file. For the
% user's convenience, we catch the error when we run into such an
% object, save it to a PNG file, then exit the loop.
%    \begin{macrocode}
          plotfilename = os.path.join(self.plotdir, 'plot-{0}.{1}'.format(counter, fmt))
          try:
              _p_.save(filename=plotfilename, **kwargs)
          except ValueError as inst:
              if 'filetype not supported by save' in str(inst):
                  newfilename = plotfilename[:-3] + 'png'
                  print '  saving {0} failed; saving to {1} instead.'.format(
                                                    plotfilename, newfilename)
                  _p_.save(filename=newfilename, **kwargs)
                  break
              else:
                  raise
%    \end{macrocode}
% If the user provides a format \emph{and} specifies the |imagemagick|
% option, we try to convert the newly-created file into EPS format.
%    \begin{macrocode}
          if format != 'notprovided' and self.useimagemagick:
              self.progress('Calling Imagemagick to convert plot-{0}.{1} to EPS'.format(
                counter, format))
              self.toeps(counter, format)
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{toeps}
% This function calls the Imagmagick utility |convert| to, well, convert
% something into EPS format. This gets called when the user has
% requested the ``|imagemagick|'' option to the \ST\ style file and is
% making a graphic file with a nondefault extension.
%    \begin{macrocode}
  def toeps(self, counter, ext):
    subprocess.check_call(['convert',\
      '{0}/plot-{1}.{2}'.format(self.plotdir, counter, ext), \
      '{0}/plot-{1}.eps'.format(self.plotdir, counter)])
%    \end{macrocode}
% We are blindly assuming that the |convert| command exists and will do
% the conversion for us; the |check_call| function raises an exception
% which, since all these calls get wrapped in try/excepts in the |.sage|
% file, should result in a reasonable error message if something strange
% happens.
% \end{macro}
%
% \begin{macro}{goboom}
% \phantomsection\label{macro:goboom}
% When a chunk of Sage code blows up, this function bears the bad news
% to the user. Normally in Python the traceback is good enough for
% this, but in this case, we start with a |.sage| file (which is
% autogenerated) which itself autogenerates a |.py| file---and the
% tracebacks the user sees refer to that file, whose line numbers are
% basically useless. We want to tell them where in the \LTX file
% things went bad, so we do that, give them the traceback, and exit
% after removing the |.sout.tmp| and |.scmd.tmp| file.
%    \begin{macrocode}
  def goboom(self, line):
    print('\n**** Error in Sage code on line {0} of {1}.tex! Traceback\
 follows.'.format(line, self.filename))
    traceback.print_exc()
    print('\n**** Running Sage on {0}.sage failed! Fix {0}.tex and try\
 again.'.format(self.filename))
    self.souttmp.close()
    os.remove(self.filename + '.sagetex.sout.tmp')
    self.scmdtmp.close()
    os.remove(self.filename + '.sagetex.scmd.tmp')
    sys.exit(int(1))
%    \end{macrocode}
% We use |int(1)| above to make sure |sys.exit| sees a Python integer;
% see
% \href{http://trac.sagemath.org/sage_trac/ticket/2861#comment:5}{ticket
% \#2861}.
% \changes{v2.0.2}{2008/04/21}{Make sure sys.exit sees a Python integer}
% \end{macro}
%
% \begin{macro}{endofdoc}
% When we're done processing, we have some cleanup tasks. We
% want to put the MD5 sum of the |.sage| file that produced the |.sout|
% file we're about to write into the |.sout| file, so that external
% programs that build \LTX documents can determine if they need to call Sage
% to update the |.sout| file. But there is a problem: we write line
% numbers to the |.sage| file so that we can provide useful error
% messages---but that means that adding non-\ST text to your
% source file will change the MD5 sum, and your program will think it
% needs to rerun Sage even though none of the actual \ST macros
% changed.
%
% How do we include line numbers for our error messages but still allow
% a program to discover a ``genuine'' change to the |.sage| file?
%
% The answer is to only find the MD5 sum of \emph{part} of the |.sage|
% file. By design, the source file line numbers only appear in calls to
% |goboom| and pause/unpause lines, so we will strip those lines out.
% What we do below is exactly equivalent to running
% \begin{center}
% \verb+egrep -v '^( _st_.goboom|print .SageT)' filename.sage | md5sum+
% \end{center}
% in a shell.
%    \begin{macrocode}
  def endofdoc(self):
    sagef = open(self.filename + '.sagetex.sage', 'r')
    m = hashlib.md5()
    for line in sagef:
      if line[0:12] != " _st_.goboom" and line[0:12] != "print 'SageT":
        m.update(line)
    s = '%' + m.hexdigest() + '% md5sum of corresponding .sage file\
 (minus "goboom" and pause/unpause lines)\n'
    self.souttmp.write(s)
    self.scmdtmp.write(s)
%    \end{macrocode}
% Now, we do issue warnings to run Sage on the |.sage| file and an
% external program might look for those to detect the need to rerun
% Sage, but those warnings do not quite capture all situations. (If
% you've already produced the |.sout| file and change a |\sage| call, no
% warning will be issued since all the |\ref|s find a |\newlabel|.)
% Anyway, I think it's easier to grab an MD5 sum out of the end of the
% file than parse the output from running |latex| on your file. (The
% regular expression |^%[0-9a-f]{32}%| will find the MD5 sum. Note that
% there are percent signs on each side of the hex string.)
%
% Now we are done with the |.sout.tmp| file. Close it, rename it, and
% tell the user we're done.
%    \begin{macrocode}
    self.souttmp.close()
    os.rename(self.filename + '.sagetex.sout.tmp', self.filename + '.sagetex.sout')
    self.scmdtmp.close()
    os.rename(self.filename + '.sagetex.scmd.tmp', self.filename + '.sagetex.scmd')
    self.progress('Sage processing complete. Run LaTeX on {0}.tex again.'.format(
             self.filename))
%    \end{macrocode}
% % \changes{v2.1.1}{2009/05/14}{Fix bug in finding md5 sum introduced by
% pause facility}
% \end{macro}

% \endinput
%</python>
% Local Variables:
% mode: doctex
% TeX-master: "sagetexpackage"
% End:
